package cn.chenxing.module.visualization.controller;

import cn.chenxing.domain.dto.TrackLine;
import cn.chenxing.domain.threadlocal.ThreadData;
import cn.chenxing.domain.util.AlertUtil;
import cn.chenxing.utils.CommonUtil;
import com.jfoenix.controls.JFXButton;
import com.jfoenix.controls.JFXComboBox;
import de.felixroske.jfxsupport.FXMLController;
import javafx.concurrent.Worker;
import javafx.fxml.FXML;
import javafx.fxml.Initializable;
import javafx.scene.web.WebEngine;
import javafx.scene.web.WebView;
import lombok.Data;
import lombok.extern.slf4j.Slf4j;
import netscape.javascript.JSObject;
import org.springframework.context.annotation.Lazy;

import java.net.URL;
import java.util.ResourceBundle;

/**
 * @Description 轨迹可视化控制层
 * @Author maogen.ymg
 * @Date 2020/4/15 19:32
 */
@Lazy
@FXMLController
@Slf4j
public class VisualTrackController implements Initializable {

    private WebEngine webEngine;

    @FXML
    private WebView webView;

    @FXML
    private JFXComboBox<Integer> zoomLevel;

    @FXML
    private JFXComboBox<String> userList;

    @FXML
    private JFXButton updateButton;

    Data2Js apps1 = new Data2Js();
    /**
     * 须公有
     * */
    @Data
    public static class Data2Js{
        public TrackLine trackLine = null;

        private String getData() {
            if(trackLine == null) {
                AlertUtil.showErrorAlert("数据读取失败", "个人轨迹数据读取失败，请检查！");
                return "";
            }

            StringBuilder sb = new StringBuilder();
            // start
            sb.append("[");

            // [[113.09988,32.70335],[112.1269,32.6976]]
            for(int i = 1; i < trackLine.getTrackPointList().size(); i++) {
                sb.append("[[").append(trackLine.getTrackPointList().get(i-1).getLongitude()).append(",")
                        .append(trackLine.getTrackPointList().get(i-1).getLatitude()).append("],[")
                        .append(trackLine.getTrackPointList().get(i).getLongitude()).append(",")
                        .append(trackLine.getTrackPointList().get(i).getLatitude()).append("]],");
            }
            sb.deleteCharAt(sb.length()-1);
            // end
            sb.append("]");
            return sb.toString();
        }

        public String getOptionJson() {
            return getData();
        }

    }

    @Override
    public void initialize(URL location, ResourceBundle resources) {

        zoomLevel.getItems().addAll(18,17,16,15,14,13,12,11,10,9,8,7,6,5);

        // 获取Engine
        webEngine = webView.getEngine();
        // 获取页面路径
        String mainUrl = getClass().getResource("/html/visualTrack.html").toExternalForm();
        // 初始化
        webEngine.load(mainUrl);

        // 设置用户列表
        CommonUtil.updateList(userList, false);

    }

    @FXML
    public void update() {
        if(ThreadData.get().getTrackData() == null) {
            AlertUtil.showWarnAlert("无法进行可视化", "还没导入数据，请选择文件菜单进行导入");
            return;
        }
        webEngine.reload();

        if("点击可视化".equals(updateButton.getText())) {
            // 设置缩放级别
            zoomLevel.setValue(calZoom());
        }

        // 传送相关数据
        transmitData2Js();
        updateButton.setText("更新");
    }

    /**
     * 传送数据给JS
     */
    private void transmitData2Js() {
        int index = userList.getSelectionModel().getSelectedIndex();

        // 数据赋值
        apps1.setTrackLine(ThreadData.get().getTrackData().getTrackLineList().get(index));

        webEngine.getLoadWorker().stateProperty().addListener((ov, oldState, newState) -> {
            if (newState == Worker.State.SUCCEEDED) {
                JSObject win = (JSObject) webEngine.executeScript("window");
                // 把对象设置成为js对象
                win.setMember("apps1",apps1);
                // 设置中心点(起始点)
                win.eval(setStartPoint());
                // 设置缩放级别
                win.eval(setZoomLevel());
                // 执行操作
                webEngine.executeScript("execute()");
            }
        });
    }

    /**
     * 传送中心点坐标
     * @return 方法名
     */
    private String setStartPoint() {
        TrackLine trackLine = apps1.trackLine;
        if(trackLine == null) {
            // 默认北京 116.40 39.90
            return "getStartPoint('116.40','39.90')";
        }
        double averLon = (trackLine.getLongitudeMax() + trackLine.getLongitudeMin())/2.0;
        double averLat = (trackLine.getLatitudeMax() + trackLine.getLatitudeMin())/2.0;
        return "getStartPoint(" + averLon + ", " + averLat + ")";
    }

    /**
     * 传送缩放级别
     * @return 方法名
     */
    private String setZoomLevel() {
        return "setZoom(" + zoomLevel.getValue() + ")";
    }

    /**
     * 根据经纬度极值计算缩放级别
     * @return Zoom
     */
    private int calZoom() {
        int index = userList.getSelectionModel().getSelectedIndex();
        if(index < 0) {
            index = 0;
        }

        TrackLine trackLine = ThreadData.get().getTrackData().getTrackLineList().get(index);

        // 缩放距离（公里，比例尺）--- 对应 18 ~ 5
        try {
            double[] zoomDist = {50, 100, 200, 500, 1000, 2000, 5000, 10000, 20000, 25000, 50000, 100000, 200000, 500000};
            double dist = CommonUtil.getDistance(trackLine.getLongitudeMin(),
                    trackLine.getLatitudeMin(), trackLine.getLongitudeMax(), trackLine.getLatitudeMax());
            if(dist == 0) {
                return 12;
            }
            for (int i = 0; i < zoomDist.length; i++) {
                // 33.4公里 对应级别为12
                if (zoomDist[i] - dist*100 > 0) {
                    return 18 - i;
                }
            }
        }catch (Exception e) {
            log.error("计算缩放级别错误，将使用默认值，原因：{}", e.getLocalizedMessage(),e);
        }
        // 默认值为12级别
        return 12;
    }

}